/**
 * <h3>OpusServiceImpl</h3>
 * <p> 作品服务实现类 </p>
 *
 * <h3>功能描述</h3>
 * <p> 实现了 {@link IOpusService} 接口中定义的作品信息增删改查业务逻辑 </p>
 * <p> 通过调用 {@link OpusMapper} 完成对数据库的操作，支持条件查询、按ID查询、更新、新增和删除等操作 </p>
 *
 * <h3>元数据</h3>
 * <ul>
 *    <li> 作者：郭强</li>
 *    <li> 创建日期：2025年05月06日 21:20:00</li>
 * </ul>
 *
 * <h3>其他信息</h3>
 * <ul>
 *    <li> 参考链接：<a href="https://example.com">官方网页</a></li>
 *    <li> 示例代码：{@code new OpusServiceImpl()} </li>
 * </ul>
 *
 * @apiNote 该类基于 MyBatis Plus 的 ServiceImpl 实现，需确保 OpusMapper 正确注入
 * @implSpec 继承自 {@link ServiceImpl<OpusMapper, OpusDTO>} 并实现 {@link IOpusService} 接口
 * @since 1.0.0
 */

package com.dnndo.system.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnndo.common.core.domain.entity.SysRole;
import com.dnndo.common.core.domain.entity.SysUser;
import com.dnndo.common.exception.ServiceException;
import com.dnndo.common.utils.bean.BeanDtoVoUtil;
import com.dnndo.system.domain.Opus;
import com.dnndo.system.domain.OpuslistsToUserInfo;
import com.dnndo.system.domain.dto.*;
import com.dnndo.system.domain.vo.*;
import com.dnndo.system.mapper.OpusMapper;
import com.dnndo.system.mapper.SysRoleMapper;
import com.dnndo.system.mapper.SysUserMapper;
import com.dnndo.system.service.IOpusService;
import com.dnndo.system.transApi.TransApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 作品服务实现类
 */
@Service
public class OpusServiceImpl extends ServiceImpl<OpusMapper, OpusDTO> implements IOpusService {

    private final OpusMapper opusMapper;

    private final SysUserMapper sysUserMapper;

    private final SysRoleMapper sysRoleMapper;

    private final TransApi transApi;

    @Autowired
    public OpusServiceImpl(OpusMapper opusMapper,  SysUserMapper sysUserMapper, SysRoleMapper sysRoleMapper, TransApi transApi) {
        this.opusMapper = opusMapper;
        this.sysUserMapper = sysUserMapper;
        this.sysRoleMapper = sysRoleMapper;
        this.transApi = transApi;
    }

    /**
     * 查询符合条件的作品列表（按用户角色分支）
     * 逻辑说明：
     * 1. 获取当前用户的角色Key集合（如admin、school、common）。
     * 2. 管理员可查询所有作品，school角色查询本校作品，common角色查询本人作品。
     * 3. 根据角色分支调用不同的Mapper方法，确保数据隔离和权限控制。
     *
     * @param dto 查询条件，包含用户ID、学校ID等
     * @return List<Opus> 作品信息列表
     */
    @Override
    public List<Opus> selectOpusList(OpusDTO dto) {
        List<String> roleKeys = getUserRoleKeys(dto.getUserId());
        List<Opus> list = new ArrayList<>();
        if (roleKeys.contains("admin")){
            // 管理员查询所有作品
            list = opusMapper.selectOpusList(dto);
        } else if (roleKeys.contains("school")) {
            setUserSchoolId(dto);
            // 学院查询本校作品
            list = opusMapper.selectSchoolOpusList(dto);
        } else if (roleKeys.contains("common")) {
            // 普通用户查询自己作品
            list = opusMapper.selectOpusListByUserId(dto);
        }
        return list;
    }

    /**
     * 获取指定用户的角色Key集合
     * 逻辑说明：
     * 1. 通过用户ID查询其所有角色。
     * 2. 提取所有角色的roleKey，返回字符串列表。
     *
     * @param userId 用户ID
     * @return List<String> 角色Key列表
     */
    private List<String> getUserRoleKeys(Integer userId) {
        List<SysRole> roles = sysRoleMapper.selectRolePermissionByUserId(userId.longValue());
        return roles.stream().map(SysRole::getRoleKey).toList();
    }

    /**
     * 设置用户所属学校ID到DTO
     * 逻辑说明：
     * 1. 通过用户ID查询用户信息。
     * 2. 将用户的schoolId赋值到DTO，便于后续按学校隔离数据。
     *
     * @param dto 作品DTO，需包含userId
     */
    private void setUserSchoolId(OpusDTO dto) {
        SysUser user = sysUserMapper.selectUserById(dto.getUserId().longValue());
        dto.setSchoolId(Integer.valueOf(user.getSchoolId()));
    }

    /**
     * 查询设计师列表（按用户角色分支）
     * 逻辑说明：
     * 1. 管理员可查询所有设计师，school角色查询本校设计师。
     * 2. 根据角色分支调用不同的Mapper方法，确保数据隔离。
     *
     * @param dto 查询条件，包含用户ID、学校ID等
     * @return List<OpusDTO> 设计师作品信息列表
     */
    @Override
    public List<OpusDTO> selectdesignerlist(OpusDTO dto) {
        List<String> roleKeys = getUserRoleKeys(dto.getUserId());
        List<OpusDTO> list = new ArrayList<>();
        if (roleKeys.contains("admin")){
            // 管理员查询所有设计师
            list = opusMapper.selectdesignerlist(dto);
        } else if (roleKeys.contains("school")) {
            setUserSchoolId(dto);
            // 学校查询本校设计师（用户在本校下有作品就是本校的设计师）
            list = opusMapper.selectSchoolDesignerList(dto);
        }
        return list;
    }

    /**
     * 根据作品ID查询作品详情，并根据用户角色注入权限信息
     * 逻辑说明：
     * 1. 查询作品详情。
     * 2. 若传入uId，获取其角色并注入到返回对象，便于前端权限判断。
     *
     * @param opusId 作品ID
     * @param uId 用户ID（可选）
     * @return OpusDTO 作品详情，含权限信息
     */
    @Override
    public OpusDTO selectOpusListById(Long opusId, Long uId) {
        OpusDTO opusDTO = opusMapper.selectOpusListById(opusId);
        if (uId != null){
            int uidInt = uId.intValue();
            List<String> roleKeys = getUserRoleKeys(uidInt);
            opusDTO.setUid(uidInt);
            if (roleKeys.contains("admin")){
                opusDTO.setRoleKey("admin");
            }
        }
        return opusDTO;
    }

    /**
     * 根据设计师ID查询其作品详情
     * 逻辑说明：
     * 1. 通过userId查询该设计师的所有作品详情。
     *
     * @param userId 设计师用户ID
     * @return OpusDTO 设计师作品详情
     */
    @Override
    public OpusDTO selectdesignerListById(Long userId) {
        return opusMapper.selectdesignerListById(userId);
    }

    /**
     * 更新作品信息（含自动翻译功能）
     * 逻辑说明：
     * 1. 若作品英文名/描述为空，则自动调用翻译接口进行翻译。
     * 2. 翻译后赋值到DTO，保证中英文信息完整。
     * 3. 更新作品信息，返回受影响行数。
     *
     * @param opusDTO 作品数据对象
     * @return int 受影响的记录数，>0表示成功
     */
    @Override
    public int updateOpusById(OpusDTO opusDTO) {
        // 判断 opusNameEn 是否为空或空字符串
        if (opusDTO.getOpusNameEn() == null || opusDTO.getOpusNameEn().isEmpty()) {
            String translatedName = translateToEnglish(opusDTO.getOpusName());
            opusDTO.setOpusNameEn(translatedName);
            try {
                Thread.sleep(1000); // 设置 1 秒间隔，防止接口限流
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        // 判断 opusDescriptionEn 是否为空或空字符串
        if (opusDTO.getOpusDescriptionEn() == null || opusDTO.getOpusDescriptionEn().isEmpty()) {
            String translatedDescription = translateToEnglish(opusDTO.getOpusDescription());
            opusDTO.setOpusDescriptionEn(translatedDescription);
        }
        int affectedRows = opusMapper.updateOpusById(opusDTO);
        return affectedRows > 0 ? opusDTO.getOpusId() : 0;
    }

    /**
     * 新增一条作品信息
     *
     * @param opusDTO 包含新增数据的OpusDTO对象
     * @return int 受影响的记录数，通常为1表示插入成功
     * @see com.dnndo.system.mapper.OpusMapper#insertOpus(OpusDTO)
     */
    @Override
    public int insertOpus(OpusDTO opusDTO) {
        // 检查用户是否已参加该主题大赛
        boolean hasJoined = checkUserJoined(
                opusDTO.getThemeId().longValue(),
                opusDTO.getUserId().longValue()
        );
        if (hasJoined) {
            throw new ServiceException("您已经参加过该主题大赛，不能重复参赛");
        }

        SysUser user = sysUserMapper.selectUserById(opusDTO.getUserId().longValue());
        if (user.getSchoolId() != null && !user.getSchoolId().isEmpty())
            opusDTO.setSchoolId(Integer.valueOf(user.getSchoolId()));

        // 判断 opusNameEn 是否为空或空字符串
        if (opusDTO.getOpusNameEn() == null || opusDTO.getOpusNameEn().isEmpty()) {
            String translatedName = translateToEnglish(opusDTO.getOpusName());
            opusDTO.setOpusNameEn(translatedName);
            try {
                Thread.sleep(1000); // 设置 1 秒间隔（单位为毫秒）
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 处理中断异常
                // 可以记录日志或进行其他处理
            }
        }

        // 判断 opusDescriptionEn 是否为空或空字符串
        if (opusDTO.getOpusDescriptionEn() == null || opusDTO.getOpusDescriptionEn().isEmpty()) {
            String translatedDescription = translateToEnglish(opusDTO.getOpusDescription());
            opusDTO.setOpusDescriptionEn(translatedDescription);
        }

        // 执行插入操作，MyBatis会自动将生成的ID设置到opusDTO中
        int affectedRows = opusMapper.insertOpus(opusDTO);

        // 返回插入的ID (通过opusDTO.getOpusId()获取)
        return affectedRows > 0 ? opusDTO.getOpusId() : 0;
    }

    /**
     * 删除指定ID的作品信息
     *
     * @param opusId 需要删除的作品的唯一标识符
     * @return int 受影响的记录数，通常为1表示删除成功
     * @see com.dnndo.system.mapper.OpusMapper#deleteOpusById(Integer)
     */
    @Override
    public int deleteOpusById(Integer opusId) {
        return opusMapper.deleteOpusById(opusId);
    }

    @Override
    public int delOpusById(Integer opusId) {
        return opusMapper.delOpusById(opusId);
    }

//    校园品牌馆接口
    @Override
    public List<BrandPavilionDTO> selectCampusBrandPavilion(BrandPavilionDTO dto) {
        if (dto.getCharacteristic().equals("全部") || dto.getCharacteristic().equals("All")){
            dto.setCharacteristic("");
        }
        if (dto.getLevel().equals("全部") || dto.getLevel().equals("All")){
            dto.setLevel("");
        }
        String language = dto.getLanguage();
        List<BrandPavilionDTO> result;
        if ("zh".equalsIgnoreCase(language)) {
            result = opusMapper.selectCampusBrandPavilionZh(dto);
        } else if ("en".equalsIgnoreCase(language)) {
            result = opusMapper.selectCampusBrandPavilionEn(dto);
        } else {
            throw new IllegalArgumentException("未知语言");
        }

        // 处理 characteristics 字段
        for (BrandPavilionDTO item : result){
            if ("zh".equals(language)) {
                // 处理中文特征字段
                String characteristic = item.getCharacteristic();
                if (characteristic != null && !characteristic.isEmpty()) {
                    String[] parts = characteristic.split("[,、]");
                    item.setCharacteristics(parts);
                } else {
                    item.setCharacteristics(new String[0]);
                }
            }
            if ("en".equals(language)) {
                // 处理英文特征字段
                String characteristicEn = item.getCharacteristicEn();
                if (characteristicEn != null && !characteristicEn.isEmpty()) {
                    String[] parts = characteristicEn.split("[,、]");
                    item.setCharacteristicsEn(parts);
                } else {
                    item.setCharacteristicsEn(new String[0]);
                }
            }
        }

        return result;
    }

    //获取校园大使（实现语言切换逻辑）
    public List<AmbassadorVO> getAmbassadorInfo(AmbassadorDTO dto) {
        List<AmbassadorVOZH> listZH;
        List<AmbassadorVOEN> listEN;
//        判断是否为空，防止空指针异常
        if (dto == null) {
            throw new IllegalArgumentException("参数 'params' 不能为空");
        }
        String language =  dto.getLanguage();
        if ("en".equalsIgnoreCase(language)) {
            listEN = opusMapper.ambassadorEn();
            return new ArrayList<>(listEN);
        }
        listZH = opusMapper.ambassador();
        return new ArrayList<>(listZH);
    }

    //获取校园设计师
    public List<DesignerVO> designer(DesignerDTO dto) {
        String language = dto.getLanguage();

        // 获取数据列表（根据语言选择不同的Mapper方法）
        List<DesignerDTO> listZh;
        List<DesignerDTO> listEn;
        if ("en".equalsIgnoreCase(language)) {
            listEn = opusMapper.designerEn();
            return new ArrayList<>(convertToListDesignerVOEN(listEn));
        } else {
            listZh = opusMapper.designer();
            return new ArrayList<>(convertToListDesignerVO(listZh));
        }
    }
    private List<DesignerVOZH> convertToListDesignerVO(List<DesignerDTO> baseList) {
        List<DesignerVOZH> resultList = new ArrayList<>();
        for (DesignerDTO baseVO : baseList) {
            DesignerVOZH designerVO = new DesignerVOZH();
            // 拷贝原始字段（保留原有数据）
            designerVO.setUserId(baseVO.getUserId());
            designerVO.setUserName(baseVO.getUserName());
            designerVO.setUserUrl(baseVO.getUserUrl());
            designerVO.setDescribe(baseVO.getDescribe());
            designerVO.setSchoolName(baseVO.getSchoolName());
            designerVO.setDesigner(baseVO.getDesigner());
            designerVO.setAmbassador(baseVO.getAmbassador());
            // 解析作品信息
            String opusId = baseVO.getOpusId();
            //String opusUrl = baseVO.getOpusUrl();
            if (opusId == null ) {
                designerVO.setWorksUrl(Collections.emptyList()); // 空列表避免 NPE
                resultList.add(designerVO);
                continue;
            }
            String[] opusIds = opusId.split(",");
            //String[] opusUrls = opusUrl.split(",");
            List<WorkUrlVO> workUrlList = new ArrayList<>();
            for (int i = 0; i < opusIds.length ; i++) {
                WorkUrlVO workUrlVO = new WorkUrlVO(); // 每次都创建新对象
                try {
                    workUrlVO.setOpusId(opusIds[i].trim());
                } catch (NumberFormatException ignored) {
                    workUrlVO.setOpusId(null); // 处理非法数字
                }
                // 根据作品id获取 作品图片url字符串
                String opusUrlsById = opusMapper.selectOpusListById(Long.valueOf(workUrlVO.getOpusId())).getOpusUrl();
                workUrlVO.setOpusUrl(new ArrayList<>(Arrays.asList(opusUrlsById.split(","))));
                workUrlList.add(workUrlVO);
            }
            designerVO.setWorksUrl(workUrlList);
            resultList.add(designerVO);
        }
        return resultList;
    }
    private List<DesignerVOEN> convertToListDesignerVOEN(List<DesignerDTO> baseList) {
        List<DesignerVOEN> resultList = new ArrayList<>();
        for (DesignerDTO baseVO : baseList) {
            DesignerVOEN designerVO = new DesignerVOEN();
            // 拷贝原始字段（保留原有数据）
            designerVO.setUserId(baseVO.getUserId());
            designerVO.setUserNameEn(baseVO.getUserNameEn());
            designerVO.setUserUrl(baseVO.getUserUrl());
            designerVO.setDescribeEn(baseVO.getDescribeEn());
            designerVO.setSchoolNameEn(baseVO.getSchoolNameEn());
            designerVO.setDesigner(baseVO.getDesigner());
            designerVO.setAmbassador(baseVO.getAmbassador());
            // 解析作品信息
            String opusId = baseVO.getOpusId();
            //String opusUrl = baseVO.getOpusUrl();
            if (opusId == null ) {
                designerVO.setWorksUrl(Collections.emptyList()); // 空列表避免 NPE
                resultList.add(designerVO);
                continue;
            }
            String[] opusIds = opusId.split(",");
            //String[] opusUrls = opusUrl.split(",");
            List<WorkUrlVO> workUrlList = new ArrayList<>();
            for (int i = 0; i < opusIds.length ; i++) {
                WorkUrlVO workUrlVO = new WorkUrlVO(); // 每次都创建新对象
                try {
                    workUrlVO.setOpusId(opusIds[i].trim());
                } catch (NumberFormatException ignored) {
                    workUrlVO.setOpusId(null); // 处理非法数字
                }
                //workUrlVO.setOpusUrl(opusUrls[i].trim());
                // 根据作品id获取 作品图片url字符串
                String opusUrlsById = opusMapper.selectOpusListById(Long.valueOf(workUrlVO.getOpusId())).getOpusUrl();
                workUrlVO.setOpusUrl(new ArrayList<>(Arrays.asList(opusUrlsById.split(","))));
                workUrlList.add(workUrlVO);
            }
            designerVO.setWorksUrl(workUrlList);
            resultList.add(designerVO);
        }
        return resultList;
    }
    //文创活动-根据作品id，查询相关作品及用户信息
    @Override
    public CulturalDTO cultural(CulturalDTO params) {
        String language =  params.getLanguage();
        CulturalDTO culturalDTO;
        if ("en".equalsIgnoreCase(language)) {
            culturalDTO = opusMapper.culturalEn(params.getOpusId());
        } else {
            culturalDTO = opusMapper.cultural(params.getOpusId());
        }

        // 对 opusUrls 进行分割并赋值给 opusUrl

        if (culturalDTO.getOpusUrls() != null && !culturalDTO.getOpusUrls().isEmpty()) {
            String[] urls = culturalDTO.getOpusUrls().split(",");
            culturalDTO.setOpusUrl(List.of(urls)); // 将数组转为 List
        } else {
            culturalDTO.setOpusUrl(Collections.emptyList()); // 防止 null
        }

        return culturalDTO;
    }

    //    根据用户id，查询该用户的所有相关作品
    @Override
    public  List<OpuslistWithUserInfoDTO> getWorkListWithUserInfo(OpuslistWithUserInfoDTO params) {
        List<OpuslistWithUserInfoDTO> listVO;

        if ("zh".equalsIgnoreCase( params.getLanguage())) {
            listVO = opusMapper.selectOpusListWithUserInfoZh(params.getUserId());
        } else if ("en".equalsIgnoreCase( params.getLanguage())) {
            listVO = opusMapper.selectOpusListWithUserInfoEn(params.getUserId());
        } else {
            throw new IllegalArgumentException("不支持的语言类型: " + params.getLanguage());
        }
        // 对 opusUrls 进行分割并赋值给 opusUrl
        for (OpuslistWithUserInfoDTO work : listVO) {
            if (work.getOpusUrls() != null && !work.getOpusUrls().isEmpty()) {
                String[] urls = work.getOpusUrls().split(",");
                work.setOpusUrl(List.of(urls)); // 将数组转为 List
            } else {
                work.setOpusUrl(Collections.emptyList()); // 防止 null
            }
        }
        return listVO;
    }


    //    首页-文创活动
    @Override
    public ApiOpusZhVO selectApiOpusActivitiesZh() {
        ApiOpusDTO apiopusDTO = opusMapper.selectApiOpusActivities();
        ApiOpusZhVO apiopusZhVO = new ApiOpusZhVO();
        // 初始化 typeData
        apiopusZhVO.setTypeData(new ApiOpusZhVO.TypeData());
        apiopusZhVO.getTypeData().setTheme(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getTheme(), ApiOpusZhVO.TypeData.Theme.class));
        apiopusZhVO.getTypeData().setAmbassador(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getAmbassador(), ApiOpusZhVO.TypeData.Ambassador.class));
        apiopusZhVO.getTypeData().setDesigner(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getDesigner(), ApiOpusZhVO.TypeData.Designer.class));
        apiopusZhVO.getTypeData().setNews(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getNews(), ApiOpusZhVO.TypeData.News.class));
        apiopusZhVO.getTypeData().setConfessionWall(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getConfessionWall(), ApiOpusZhVO.TypeData.ConfessionWall.class));
        apiopusZhVO.getTypeData().setShoppingMall(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getShoppingMall(), ApiOpusZhVO.TypeData.ShoppingMall.class));
        apiopusZhVO.setHotList(BeanDtoVoUtil.listVo(apiopusDTO.getHotList(), ApiOpusZhVO.HotUser.class));
        return apiopusZhVO;
    }

    @Override
    public ApiOpusEnVO selectApiOpusActivitiesEn() {
        ApiOpusDTO apiopusDTO = opusMapper.selectApiOpusActivities();
        ApiOpusEnVO apiopusEnVO = new ApiOpusEnVO();
        // 初始化 typeData
        apiopusEnVO.setTypeData(new ApiOpusEnVO.TypeData());
        apiopusEnVO.getTypeData().setTheme(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getTheme(), ApiOpusEnVO.TypeData.Theme.class));
        apiopusEnVO.getTypeData().setAmbassador(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getAmbassador(), ApiOpusEnVO.TypeData.Ambassador.class));
        apiopusEnVO.getTypeData().setDesigner(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getDesigner(), ApiOpusEnVO.TypeData.Designer.class));
        apiopusEnVO.getTypeData().setNews(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getNews(), ApiOpusEnVO.TypeData.News.class));
        apiopusEnVO.getTypeData().setConfessionWall(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getConfessionWall(), ApiOpusEnVO.TypeData.ConfessionWall.class));
        apiopusEnVO.getTypeData().setShoppingMall(BeanDtoVoUtil.convert(apiopusDTO.getTypeData().getShoppingMall(), ApiOpusEnVO.TypeData.ShoppingMall.class));
        apiopusEnVO.setHotList(BeanDtoVoUtil.listVo(apiopusDTO.getHotList(), ApiOpusEnVO.HotUser.class));
        return apiopusEnVO;
    }

    @Override
    public boolean checkUserJoined(Long themeId, Long userId) {
        int count = opusMapper.checkUserJoined(themeId, userId);
        return count > 0;
    }

  @Override
  public OpusDTO selectOpusById(Long opusId) {
    return opusMapper.selectOpusById(opusId);
  }

    /**
     * 根据主题ID计算该主题下所有作品的积分，并进行排名，同时为前五名用户授予“校园大使”头衔。
     *
     * <h3>业务逻辑说明</h3>
     * <ol>
     *     <li>查询指定主题下的所有作品信息。</li>
     *     <li>遍历作品列表，根据点赞数和浏览数计算积分（积分 = (点赞数 + 浏览数) / 100）。</li>
     *     <li>对积分结果进行合法性校验，防止负值或异常数值。</li>
     *     <li>根据积分对作品进行降序排序（积分高的作品排在前面）。</li>
     *     <li>更新每部作品的排名信息。</li>
     *     <li>为积分排名前五的用户授予“校园大使”头衔（设置 ranks = 1）。</li>
     * </ol>
     *
     * <h3>异常处理</h3>
     * <ul>
     *     <li>如果积分计算过程中出现除以零或非法数值，抛出 ArithmeticException。</li>
     *     <li>如果点赞数或浏览数为负数，抛出 IllegalArgumentException。</li>
     *     <li>上述异常会被捕获并包装为 ServiceException 抛出，分别返回 500 和 400 错误码。</li>
     * </ul>
     *
     * <h3>参数说明</h3>
     * @param themeId 主题ID，用于筛选需要计算积分和排名的作品
     *
     * <h3>使用的技术点</h3>
     * <ul>
     *     <li>{@link BigDecimal}：用于精确计算积分，避免浮点数精度问题。</li>
     *     <li>{@link List#sort(java.util.Comparator)}：对作品列表进行排序。</li>
     *     <li>{@link OpusMapper#updateOpusById(OpusDTO)}：更新作品排名。</li>
     *     <li>{@link SysUserMapper#selectUserById(Long)} 和 {@link SysUserMapper#updateUser(SysUser)}：更新用户头衔。</li>
     * </ul>
     *
     * <h3>注意事项</h3>
     * <ul>
     *     <li>积分保留两位小数，并使用 HALF_UP 模式进行四舍五入。</li>
     *     <li>排名更新后，前五名用户将获得“校园大使”头衔（ranks = 1）。</li>
     *     <li>如果作品数量不足5个，只授予实际数量的“校园大使”头衔。</li>
     * </ul>
     */
    @Override
    public void calculateAndRankOpusByThemeId(Integer themeId) {
        try {
            // 查询指定 themeId 的所有作品
            List<OpusDTO> opusList = opusMapper.selectOpusByThemeId(themeId);

            // 2. 遍历作品列表，计算每个作品的积分
            for (OpusDTO opus : opusList) {
                // 从作品对象 opus 中获取点赞数 totalLikes 和浏览量 pageView，若为 null 则默认赋值为 0，防止后续计算时出现空指针异常。
                int totalLikes = opus.getTotalLikes() != null ? opus.getTotalLikes() : 0;
                int pageView = opus.getPageView() != null ? opus.getPageView() : 0;

                // 校验输入是否为非负整数
                if (totalLikes < 0 || pageView < 0) {
                    throw new IllegalArgumentException("点赞数和浏览数不能为负数");
                }
                // 计算积分（浏览量+点赞数）
                BigDecimal sum = new BigDecimal(totalLikes + pageView);
                // 定义一个除数 divisor 为 100，用于后续计算积分
                BigDecimal divisor = new BigDecimal(100);

                // 防止除以零
                if (divisor.compareTo(BigDecimal.ZERO) == 0) {
                    throw new ArithmeticException("除数不能为零");
                }
                // 将作品的点赞数与浏览量之和 sum 除以 100，四舍五入并保留两位小数
                BigDecimal gradeValue = sum.divide(divisor, 2, RoundingMode.HALF_UP);

                // 确保结果是合法数值（不是无穷大、NaN等）
                if (gradeValue.compareTo(BigDecimal.ZERO) < 0 || gradeValue.stripTrailingZeros().toPlainString().contains("E")) {
                    throw new ArithmeticException("积分计算结果异常：" + gradeValue.toPlainString());
                }
                // 去掉无效的0，如 0.0100 -> 0.01
                opus.setGrade(gradeValue.stripTrailingZeros().toPlainString());
            }


            // 3. 根据积分进行排序
            opusList.sort((o1, o2) -> {
                // 将作品积分字符串转换为 BigDecimal 类型，以便进行精确的数值比较和排序操作
                BigDecimal grade1 = new BigDecimal(o1.getGrade());
                BigDecimal grade2 = new BigDecimal(o2.getGrade());
                return grade2.compareTo(grade1); // 降序排序
            });

            // 4. 更新作品积分排名
            for (int i = 0; i < opusList.size(); i++) {
                OpusDTO opus = opusList.get(i);
                // 设置排名
                opus.setRanking(String.valueOf(i + 1));
                opusMapper.updateOpusById(opus);
            }

            // 5. 为前五设置校园大使头衔
            int topFiveLimit = Math.min(5, opusList.size());
            for (int i = 0; i < topFiveLimit; i++) {
                OpusDTO topOpus = opusList.get(i);
                Integer userId = topOpus.getUserId();

                // 更新用户表中的 ranks 字段
                SysUser user = sysUserMapper.selectUserById(userId.longValue());
                if (user != null) {
                    user.setRanks(1);
                    sysUserMapper.updateUser(user);
                }
            }
        } catch (ArithmeticException e) {
            throw new ServiceException("积分计算异常", 500).setDetailMessage(e.getMessage());
        } catch (IllegalArgumentException e) {
            throw new ServiceException("参数验证失败", 400).setDetailMessage(e.getMessage());
        }

    }

//    翻译
    private String translateToEnglish(String text) {
        if (text == null || text.isEmpty()) {
            return "";
        }
        JSONObject transResult = transApi.getTransResult(text, "zh", "en");
        JSONArray transArray = transResult.getJSONArray("trans_result");
        if (transArray != null && !transArray.isEmpty()) {
            JSONObject firstItem = transArray.getJSONObject(0);
            return firstItem.getString("dst");
        }
        return "";
    }

    //  查询校园品牌馆信息的总记录数
    @Override
    public int countCampusBrandPavilion(BrandPavilionDTO dto) {
        if (dto.getLanguage().equals("en"))
            return opusMapper.countCampusBrandPavilionEn(dto);
        else
            return opusMapper.countCampusBrandPavilionZh(dto);
    }

    //  查询校园大使的总记录数
    @Override
    public int countAmbassador(AmbassadorDTO dto) {
        return opusMapper.countAmbassador(dto);
    }
    //  查询设计师的总记录数
    @Override
    public int countDesigner(DesignerDTO dto) {
        return opusMapper.countDesigner(dto);
    }

    //  查询根据用户id，查询该用户的所有相关作品总数
    @Override
    public int countWorkListWithUserInfo(OpuslistWithUserInfoDTO dto) {
        return opusMapper.countWorkListWithUserInfo(dto);
    }

  @Override
  public List<OpuslistsToUserInfo> getOpusListsByUserId(OpuslistsToUserInfo opuslistsToUserInfo) {
    return opusMapper.getOpusListsByUserId(opuslistsToUserInfo);
  }

}
